package com.oren.proxy;

import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author oren
 * @time 2018/7/3 21:44
 * @description 代理链的一个实体类
 * @Since jdk1.7
 */
public class ProxyChain {

	private final Class<?> targetClass;//目标类

	private final Object targetObject ;//目标对象

	private final Method targetMethod;//目标方法

	private final MethodProxy methodProxy;//方法代理

	private final Object[] methodParams;//方法参数

	private List<Proxy> proxyList=new ArrayList<Proxy>();//代理列表

	private int proxyIndex=0;//代理索引

	public ProxyChain(Class<?> targetClass, Object targetObject, Method targetMethod, MethodProxy methodProxy, Object[] methodParams, List<Proxy> proxyList) {
		this.targetClass = targetClass;
		this.targetObject = targetObject;
		this.targetMethod = targetMethod;
		this.methodProxy = methodProxy;
		this.methodParams = methodParams;
		this.proxyList = proxyList;
	}

	public Class<?> getTargetClass() {
		return targetClass;
	}

	public Method getTargetMethod() {
		return targetMethod;
	}

	public Object[] getMethodParams() {
		return methodParams;
	}

	/**
	 * 我们通过proxyIndex来充当代理对象的计数器
	 * 若尚未达到proxyList的上限，则从proxyList中取出相应的proxy对象
	 * 并调用其proxy的方法。在proxy接口的实现中会提供相应的横切逻辑，并调用doProxyChain方法，
	 * 直到proxyList达到上限，就会调用cglib的invokeSuper（）方法执行所要执行的业务处理
	 * @return
	 * @throws Throwable
	 */
	public Object doProxyChain()throws Throwable{
		Object methodResult;
		if(proxyIndex<proxyList.size()){
			methodResult=proxyList.get(proxyIndex++).doProxy(this);
		}else{
			methodResult=methodProxy.invokeSuper(targetObject,methodParams);
		}
		return methodResult;
	}
}
